package example.classlevel;

import graph.mpg.DataFlowGraphConstructor;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.border.BevelBorder;


import spec.ecore.EcoreParser;
import spec.ecore.EcoreStruct;

import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.ecore.EClassifier;
import org.eclipse.emf.ecore.EPackage;
import org.eclipse.emf.ecore.impl.EPackageImpl;
import org.xml.sax.SAXException;

import spec.ocl_mpg.OCLReader;
import spec.ocl_mpg.OCLTree;
import spec.state.SDReader;
import testcasegenerator.clp.classlevel.TestDataGenerator;
import testcasegenerator.pathenumerator.DataFlowPathEnum;
import testcodegenerator.classlevel.JUnitCodeGenerator;




@SuppressWarnings("serial")
public class GUI extends JFrame {
	String ecoreFile = null;
	String OCLFile = null;
	String UMLFile = null;
	private List<OCLTree> list;
	SDReader Reader;
	TestDataGenerator DataGenerator;
	JUnitCodeGenerator jcode;
	ArrayList<String> List_import;
	
	private JButton a1 = new JButton("Read UML Class Diagram");
	private JButton a2 = new JButton("Read OCL File");
	private JButton a3 = new JButton("Read UML State Diagram");
	private JButton a4 = new JButton("Generate Test Class");

	private String path;
	
	
	
	public GUI(){
		
		//infeasiblePath.settBlockPath(path.getBlockPath());
        a1.setBounds(10	, 10, 200 , 50);
        a2.setBounds(220 , 10 , 200 , 50);
        a3.setBounds(430 , 10 , 200 , 50);
        a4.setBounds(680, 10 , 200 , 50);
       
		setLayout(null);
		add(a1);
		add(a2);
		add(a3);
		add(a4);		
		
		a1.setBorder(new BevelBorder(BevelBorder.RAISED));
		a2.setBorder(new BevelBorder(BevelBorder.RAISED));
		a3.setBorder(new BevelBorder(BevelBorder.RAISED));
		a4.setBorder(new BevelBorder(BevelBorder.RAISED));
		   
		
	    a4.setVisible(false);
	   
		
		a1.setToolTipText("Select the Ecore diagram file , file name should be .ecore");
		a2.setToolTipText("Select the OCL file , file name should be .spec.ocl_mpg");
		a3.setToolTipText("Select the UML State diagram file , file name should be .uml");
		
		/*
		 * select Ecore File
		 */
		a1.addActionListener(new ActionListener() {
			
			public void actionPerformed(ActionEvent e) {
			
				JFileChooser c = new JFileChooser("C:\\");
				//Demonstrate "Ecore Diagram
				if (c.showOpenDialog(null) == JFileChooser.APPROVE_OPTION) {
					File file = c.getSelectedFile();
					String file_path = c.getSelectedFile().getPath();
					//a5.append("You have select a Ecore File : "+file_path+"\n");
					
				    ecoreFile = file_path;
				    path = file_path;
				    try {
						path = getPath();
					} catch (IOException e1) {
						// TODO Auto-generated catch block
						e1.printStackTrace();
					}
				    
					
				}
				
			}
		});
		

		/*
		 * select OCL File
		 */
		a2.addActionListener(new ActionListener() {
			
			public void actionPerformed(ActionEvent e) {
				
				JFileChooser c = new JFileChooser(path);
				//Demonstrate OCL
				if (c.showOpenDialog(null) == JFileChooser.APPROVE_OPTION) {
					File file = c.getSelectedFile();
					String file_path = c.getSelectedFile().getPath();
					//a5.append("You have select a OCL File : "+file_path+"\n");
					OCLFile = file_path;
					
					OCLReader parser = new OCLReader();
					
					File EcoreFile = new File(ecoreFile);
					File oclFile = new File(OCLFile);
					
		
					
					ArrayList<EPackageImpl> list_pack = EcoreParser.parsingDocuments(EcoreFile);
					list = parser.parseDocument(oclFile, list_pack);
					
					ArrayList<String> list_import = listImportPackage(list_pack);
					
					List_import = (ArrayList<String>) list_import.clone();
					
					EcoreStruct eStruct = new EcoreStruct(list_pack);
					for (OCLTree next : list) {
						ArrayList<String[]> var_list = eStruct.searchVariable(next
								.getClassName(), next.getMethodName());
						ArrayList<String[]> paramList = eStruct.searchParamVariable(
								next.getClassName(), next.getMethodName());

						next.setParam_list(paramList);
						next.setVar_list(var_list);
						next.setDefUse();			
					}
					
				}
				
			}
		});
		

		/*
		 * select UML State File
		 */
        a3.addActionListener(new ActionListener() {
			
			public void actionPerformed(ActionEvent e) {
				
				JFileChooser c = new JFileChooser(path);
				//Demonstrate "Ecore Diagram
				if (c.showOpenDialog(null) == JFileChooser.APPROVE_OPTION) {
					File file = c.getSelectedFile();
					String file_path = c.getSelectedFile().getPath();
					//a5.append("You have select a UML File : "+file_path+"\n");
					
						UMLFile = file_path;
						
						SDReader reader;
						try {
							reader = new SDReader();
							reader.parseDocument(UMLFile);
							Reader = reader;
						} catch (SAXException e1) {
							// TODO Auto-generated catch block
							//a5.append("File error , File should be .uml");
						} catch (IOException e1) {
							// TODO Auto-generated catch block
							//a5.append("IOEeception");
						} 
						
						a4.setVisible(true);
					
					
				}
				
			}
		});
        
        /*
         *    change to b
         */
        a4.addActionListener(new ActionListener() {
        	
			
			private JUnitCodeGenerator JCode;

			public void actionPerformed(ActionEvent e) {
									
				
				
				DataFlowGraphConstructor flowgraph = new DataFlowGraphConstructor(Reader.AllTransitions, list);
				flowgraph.buildDataFlowGraph();
				flowgraph.dataFlowAnalysis();
				
				DataFlowPathEnum genpath = new DataFlowPathEnum(flowgraph);
				
				
				TestDataGenerator dataGenerator = new TestDataGenerator(flowgraph , genpath ,list ,Reader.AllTransitions);
				
				DataGenerator = dataGenerator;

				JFileChooser c = new JFileChooser(path);
				if (c.showSaveDialog(null) == JFileChooser.APPROVE_OPTION) {
					File file = c.getSelectedFile();
					String file_path = c.getSelectedFile().getPath();
					
					JUnitCodeGenerator Jcode = new JUnitCodeGenerator(DataGenerator.getexecuter() , List_import ,list.get(0).getClassName(), file_path);
				    Jcode.writeJUnitFile(file_path);
				    
				    JCode = Jcode;
				}
				
				jcode = JCode;
				
				showInformation();					
			}
		});     
	}
	
	
	public void showInformation(){
		run(new GUI2(this),1100,900);
	}
	
	public static void run(final JFrame f,final int width , final int height){
		SwingUtilities.invokeLater(new Runnable() {
			
			public void run() {
				f.setTitle("Test Class Generator");
				f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
				f.setSize(width,height);
				f.setVisible(true);
				f.setResizable(false);
				
			}
		});
	}
	
	
	public static void main(String[] args) throws InterruptedException{
		try{
			UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
		}
		catch(Exception e){
			
		}
		run(new GUI() , 900 ,100);		

	}
	
	
	
	//get library
	public String getPath() throws IOException{
		File file = new File(path);
		String newPath ="";
		newPath = file.getCanonicalPath();

		return newPath;
		
		
	}
	
	public JUnitCodeGenerator getJcode(){
		JUnitCodeGenerator Jcode = jcode;
		return jcode;
	}
	
	public SDReader getReader(){
		SDReader reader = Reader;
		return reader;
	}
	
	public TestDataGenerator getDataGenerator(){
		TestDataGenerator DataGenerator = this.DataGenerator;
		return DataGenerator;
	}
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	private static ArrayList<String> listImportPackage(ArrayList<String> list,
			String parent, EList<EPackage> pack_list) {

		for (EPackage pack : pack_list) {
			EList<EPackage> sub_list = pack.getESubpackages();
			if (pack_list.size() > 0) {
				listImportPackage(list, String.format("%s.%s", parent, pack
						.getName()), sub_list);
			}

			EList<EClassifier> class_list = pack.getEClassifiers();
			if (class_list.size() > 0) {
				for (EClassifier next : class_list) {
					list.add(String.format("%s.%s.%s", parent, pack.getName(),
							next.getName()));
				}
			}
		}

		return list;
	}
	
	private static ArrayList<String> listImportPackage(
			ArrayList<EPackageImpl> list_pack) {

		ArrayList<String> list = new ArrayList<String>();

		for (EPackageImpl pack : list_pack) {
			EList<EPackage> sub_list = pack.getESubpackages();
			if (sub_list.size() > 0) {
				listImportPackage(list, pack.getName(), sub_list);
			}

			EList<EClassifier> class_list = pack.getEClassifiers();
			if (class_list.size() > 0) {
				for (EClassifier next : class_list) {
					list.add(String.format("%s.%s", pack.getName(), next
							.getName()));
				}
			}
		}

		return list;
	}
	
	



	
	
	
	

}
